Vault userpass: Enable renewals for login tokens

This commit is contained in:
vishalnayak 2015-09-16 20:12:41 -04:00
parent 8f79e8be82
commit 4332eb9d05
3 changed files with 63 additions and 2 deletions

View File

@ -3,7 +3,6 @@ package userpass
import (
"crypto/subtle"
"strings"
"time"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
@ -68,6 +67,11 @@ func (b *backend) pathLogin(
"username": username,
},
DisplayName: username,
LeaseOptions: logical.LeaseOptions{
TTL: user.TTL,
GracePeriod: user.TTL / 10,
Renewable: user.TTL > 0,
},
},
}, nil
}
@ -84,7 +88,7 @@ func (b *backend) pathLoginRenew(
return nil, nil
}
return framework.LeaseExtend(1*time.Hour, 0, false)(req, d)
return framework.LeaseExtend(user.MaxTTL, 0, false)(req, d)
}
const pathLoginSyn = `

View File

@ -1,7 +1,9 @@
package userpass
import (
"fmt"
"strings"
"time"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
@ -26,6 +28,16 @@ func pathUsers(b *backend) *framework.Path {
Type: framework.TypeString,
Description: "Comma-separated list of policies",
},
"ttl": &framework.FieldSchema{
Type: framework.TypeString,
Default: "",
Description: "The lease duration which decides login expiration",
},
"max_ttl": &framework.FieldSchema{
Type: framework.TypeString,
Default: "",
Description: "Maximum duration after which login should expire",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
@ -98,10 +110,19 @@ func (b *backend) pathUserWrite(
return nil, err
}
ttlStr := d.Get("ttl").(string)
maxTTLStr := d.Get("max_ttl").(string)
ttl, maxTTL, err := b.SanitizeTTL(ttlStr, maxTTLStr)
if err != nil {
return logical.ErrorResponse(fmt.Sprintf("err: %s", err)), nil
}
// Store it
entry, err := logical.StorageEntryJSON("user/"+name, &UserEntry{
PasswordHash: hash,
Policies: policies,
TTL: ttl,
MaxTTL: maxTTL,
})
if err != nil {
return nil, err
@ -123,6 +144,12 @@ type UserEntry struct {
PasswordHash []byte
Policies []string
// Duration after which the user will be revoked unless renewed
TTL time.Duration
// Maximum duration for which user can be valid
MaxTTL time.Duration
}
const pathUserHelpSyn = `

View File

@ -174,6 +174,36 @@ func (b *Backend) System() logical.SystemView {
return b.system
}
// This method takes in the TTL and MaxTTL values provided by the user, compares
// those with the SystemView values. If they are empty default values are set.
// If they are set, their boundaries are validated.
func (b *Backend) SanitizeTTL(ttlStr, maxTTLStr string) (ttl, maxTTL time.Duration, err error) {
if len(ttlStr) == 0 {
ttl = b.System().DefaultLeaseTTL()
} else {
ttl, err = time.ParseDuration(ttlStr)
if err != nil {
return 0, 0, fmt.Errorf("Invalid ttl: %s", err)
}
}
sysMaxTTL := b.System().MaxLeaseTTL()
if len(maxTTLStr) == 0 {
maxTTL = sysMaxTTL
} else {
maxTTL, err = time.ParseDuration(maxTTLStr)
if err != nil {
return 0, 0, fmt.Errorf("Invalid max_ttl: %s", err)
}
}
if maxTTL > sysMaxTTL {
maxTTL = sysMaxTTL
}
if ttl > maxTTL {
ttl = maxTTL
}
return
}
// Route looks up the path that would be used for a given path string.
func (b *Backend) Route(path string) *Path {
result, _ := b.route(path)