2015-04-11 21:46:09 +00:00
|
|
|
package framework
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/hashicorp/vault/logical"
|
|
|
|
)
|
|
|
|
|
|
|
|
// LeaseExtend returns an OperationFunc that can be used to simply extend
|
|
|
|
// the lease of the auth/secret for the duration that was requested. Max
|
|
|
|
// is the max time past the _current_ time that a lease can be extended. i.e.
|
|
|
|
// setting it to 2 hours forces a renewal within the next 2 hours again.
|
2015-04-11 23:41:08 +00:00
|
|
|
//
|
|
|
|
// maxSession is the maximum session length allowed since the original
|
2015-06-17 21:16:44 +00:00
|
|
|
// issue time. If this is zero, it is ignored.
|
2015-06-17 21:24:12 +00:00
|
|
|
//
|
|
|
|
// maxFromLease controls if the maximum renewal period comes from the existing
|
|
|
|
// lease. This means the value of `max` will be replaced with the existing
|
|
|
|
// lease duration.
|
|
|
|
func LeaseExtend(max, maxSession time.Duration, maxFromLease bool) OperationFunc {
|
2015-04-11 21:46:09 +00:00
|
|
|
return func(req *logical.Request, data *FieldData) (*logical.Response, error) {
|
2015-08-21 05:27:01 +00:00
|
|
|
leaseOpts := detectLease(req)
|
|
|
|
if leaseOpts == nil {
|
2015-04-11 21:46:09 +00:00
|
|
|
return nil, fmt.Errorf("no lease options for request")
|
|
|
|
}
|
|
|
|
|
2015-06-17 21:24:12 +00:00
|
|
|
// Check if we should limit max
|
|
|
|
if maxFromLease {
|
2015-08-21 05:27:01 +00:00
|
|
|
max = leaseOpts.TTL
|
2015-06-17 21:24:12 +00:00
|
|
|
}
|
|
|
|
|
2015-06-17 21:16:44 +00:00
|
|
|
// Sanity check the desired increment
|
|
|
|
switch {
|
|
|
|
// Protect against negative leases
|
2015-08-21 05:27:01 +00:00
|
|
|
case leaseOpts.Increment < 0:
|
2015-06-17 21:16:44 +00:00
|
|
|
return logical.ErrorResponse(
|
|
|
|
"increment must be greater than 0"), logical.ErrInvalidRequest
|
|
|
|
|
2015-08-21 05:27:01 +00:00
|
|
|
// If no lease increment, or too large of an increment, use the max
|
|
|
|
case max > 0 && leaseOpts.Increment == 0, max > 0 && leaseOpts.Increment > max:
|
|
|
|
leaseOpts.Increment = max
|
2015-06-17 21:16:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get the current time
|
2015-04-11 23:41:08 +00:00
|
|
|
now := time.Now().UTC()
|
|
|
|
|
|
|
|
// Check if we're passed the issue limit
|
|
|
|
var maxSessionTime time.Time
|
|
|
|
if maxSession > 0 {
|
2015-08-21 05:27:01 +00:00
|
|
|
maxSessionTime = leaseOpts.IssueTime.Add(maxSession)
|
2015-06-17 21:16:44 +00:00
|
|
|
if maxSessionTime.Before(now) {
|
2015-04-11 23:41:08 +00:00
|
|
|
return logical.ErrorResponse(fmt.Sprintf(
|
|
|
|
"lease can only be renewed up to %s past original issue",
|
|
|
|
maxSession)), logical.ErrInvalidRequest
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-21 05:27:01 +00:00
|
|
|
// The new lease is the minimum of the requested Increment
|
2015-06-17 21:16:44 +00:00
|
|
|
// or the maxSessionTime
|
2015-08-21 05:27:01 +00:00
|
|
|
requestedLease := now.Add(leaseOpts.Increment)
|
2015-06-17 21:16:44 +00:00
|
|
|
if !maxSessionTime.IsZero() && requestedLease.After(maxSessionTime) {
|
|
|
|
requestedLease = maxSessionTime
|
2015-04-11 23:41:08 +00:00
|
|
|
}
|
|
|
|
|
2015-04-11 21:46:09 +00:00
|
|
|
// Determine the requested lease
|
2015-06-17 21:16:44 +00:00
|
|
|
newLeaseDuration := requestedLease.Sub(now)
|
2015-04-11 21:46:09 +00:00
|
|
|
|
|
|
|
// Set the lease
|
2015-08-21 05:27:01 +00:00
|
|
|
leaseOpts.TTL = newLeaseDuration
|
2015-08-21 00:47:17 +00:00
|
|
|
|
2015-04-11 21:46:09 +00:00
|
|
|
return &logical.Response{Auth: req.Auth, Secret: req.Secret}, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func detectLease(req *logical.Request) *logical.LeaseOptions {
|
|
|
|
if req.Auth != nil {
|
|
|
|
return &req.Auth.LeaseOptions
|
|
|
|
} else if req.Secret != nil {
|
|
|
|
return &req.Secret.LeaseOptions
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|