-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alex/add max num uses to tokenhelper v2 #6701
Changes from 4 commits
2b37059
c598e74
26b778f
2bd0c21
ce353a2
bd53597
7ad55ac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,9 @@ type TokenParams struct { | |
|
||
// The TTL to user for the token | ||
TokenTTL time.Duration `json:"token_ttl" mapstructure:"token_ttl"` | ||
|
||
// The maximum number of times a token issued from this role may be used. | ||
TokenMaxNumUses int `json:"token_max_num_uses" mapstructure:"token_max_num_uses"` | ||
} | ||
|
||
// AddTokenFields adds fields to an existing role. It panics if it would | ||
|
@@ -101,6 +104,11 @@ func TokenFields() map[string]*framework.FieldSchema { | |
Type: framework.TypeDurationSecond, | ||
Description: "The initial ttl of the token to generate", | ||
}, | ||
|
||
"token_max_num_uses": &framework.FieldSchema{ | ||
Type: framework.TypeInt, | ||
Description: "The maximum number of times a token issued from this role may be used.", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should add to the description that in order to remove the limit/max, to set this value to |
||
}, | ||
} | ||
} | ||
|
||
|
@@ -167,6 +175,13 @@ func (t *TokenParams) ParseTokenFields(req *logical.Request, d *framework.FieldD | |
return errors.New("'token_ttl' cannot be greater than 'token_max_ttl'") | ||
} | ||
|
||
if tokenMaxNumUses, ok := d.GetOk("token_max_num_uses"); ok { | ||
t.TokenMaxNumUses = tokenMaxNumUses.(int) | ||
} | ||
if t.TokenMaxNumUses < 0 { | ||
return errors.New("'token_max_num_uses' cannot be negative") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
|
@@ -179,6 +194,7 @@ func (t *TokenParams) PopulateTokenData(m map[string]interface{}) { | |
m["token_policies"] = t.TokenPolicies | ||
m["token_type"] = t.TokenType.String() | ||
m["token_ttl"] = t.TokenTTL.Seconds() | ||
m["token_max_num_uses"] = t.TokenMaxNumUses | ||
} | ||
|
||
func (t *TokenParams) PopulateTokenAuth(auth *logical.Auth) { | ||
|
@@ -190,6 +206,7 @@ func (t *TokenParams) PopulateTokenAuth(auth *logical.Auth) { | |
auth.Policies = t.TokenPolicies | ||
auth.TokenType = t.TokenType | ||
auth.TTL = t.TokenTTL | ||
auth.NumUses = t.TokenMaxNumUses | ||
} | ||
|
||
const ( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -397,6 +397,12 @@ func (ts *TokenStore) paths() []*framework.Path { | |
Description: "(DEPRECATED) Use 'token_bound_cidrs' instead. If this and 'token_bound_cidrs' are both specified both will be retained but 'token_bound_cidrs' will take precedence.", | ||
Deprecated: true, | ||
}, | ||
|
||
"token_max_num_uses": &framework.FieldSchema{ | ||
Type: framework.TypeInt, | ||
Description: "The maximum number of times a token issued from this role can be used", | ||
Deprecated: true, | ||
}, | ||
}, | ||
|
||
Callbacks: map[logical.Operation]framework.OperationFunc{ | ||
|
@@ -409,7 +415,7 @@ func (ts *TokenStore) paths() []*framework.Path { | |
ExistenceCheck: ts.tokenStoreRoleExistenceCheck, | ||
} | ||
|
||
tokenhelper.AddTokenFieldsWithAllowList(rolesPath.Fields, []string{"token_bound_cidrs", "token_explicit_max_ttl", "token_period", "token_type", "token_no_default_policy"}) | ||
tokenhelper.AddTokenFieldsWithAllowList(rolesPath.Fields, []string{"token_bound_cidrs", "token_explicit_max_ttl", "token_period", "token_type", "token_no_default_policy", "token_num_uses"}) | ||
p = append(p, rolesPath) | ||
|
||
return p | ||
|
@@ -2234,6 +2240,16 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque | |
renewable = false | ||
} | ||
|
||
// Update num_uses which is equal to req.Data["num_uses"] at this point | ||
// 0 means unlimited so 1 is actually less than 0 | ||
switch { | ||
case role.TokenMaxNumUses > 0 && te.NumUses == 0: | ||
te.NumUses = role.TokenMaxNumUses | ||
case role.TokenMaxNumUses < te.NumUses: | ||
te.NumUses = role.TokenMaxNumUses | ||
default: | ||
} | ||
|
||
if role.PathSuffix != "" { | ||
te.Path = fmt.Sprintf("%s/%s", te.Path, role.PathSuffix) | ||
} | ||
|
@@ -2969,6 +2985,7 @@ func (ts *TokenStore) tokenStoreRoleRead(ctx context.Context, req *logical.Reque | |
"path_suffix": role.PathSuffix, | ||
"renewable": role.Renewable, | ||
"token_type": role.TokenType.String(), | ||
"token_max_num_uses": role.TokenMaxNumUses, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we omit this if the value is zero? It may be confusing to users |
||
}, | ||
} | ||
|
||
|
@@ -3149,6 +3166,12 @@ func (ts *TokenStore) tokenStoreRoleCreateUpdate(ctx context.Context, req *logic | |
} | ||
} | ||
|
||
// no legacy version without the token_ prefix to check for | ||
tokenMaxNumUses, ok := data.GetOk("token_max_num_uses") | ||
catsby marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if ok { | ||
entry.TokenMaxNumUses = tokenMaxNumUses.(int) | ||
} | ||
|
||
// Run validity checks on token type | ||
if entry.TokenType == logical.TokenTypeBatch { | ||
if !entry.Orphan { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use
omitempty
here? Assuming this value gets output to the user at some point, I wonder if0
would be confusing. Internally zero means "unlimited" but that's mostly an implementation detail, yeah?