diff --git a/api/secret.go b/api/secret.go index 438279bb00..378f287078 100644 --- a/api/secret.go +++ b/api/secret.go @@ -3,6 +3,7 @@ package api import ( "encoding/json" "io" + "time" ) // Secret is the structure returned for every secret within Vault. @@ -32,9 +33,9 @@ type Secret struct { // SecretWrapInfo contains wrapping information if we have it. type SecretWrapInfo struct { - Token string `json:"token"` - TTL int `json:"ttl"` - CreationTime int64 `json:"creation_time"` + Token string `json:"token"` + TTL int `json:"ttl"` + CreationTime time.Time `json:"creation_time"` } // SecretAuth is the structure containing auth information if we have it. diff --git a/api/secret_test.go b/api/secret_test.go index ec4ee48582..c4efc9b698 100644 --- a/api/secret_test.go +++ b/api/secret_test.go @@ -4,6 +4,7 @@ import ( "reflect" "strings" "testing" + "time" ) func TestParseSecret(t *testing.T) { @@ -21,10 +22,12 @@ func TestParseSecret(t *testing.T) { "wrap_info": { "token": "token", "ttl": 60, - "creation_time": 100000 + "creation_time": "2016-06-07T15:52:10-04:00" } }`) + rawTime, _ := time.Parse(time.RFC3339, "2016-06-07T15:52:10-04:00") + secret, err := ParseSecret(strings.NewReader(raw)) if err != nil { t.Fatalf("err: %s", err) @@ -43,10 +46,10 @@ func TestParseSecret(t *testing.T) { WrapInfo: &SecretWrapInfo{ Token: "token", TTL: 60, - CreationTime: int64(100000), + CreationTime: rawTime, }, } if !reflect.DeepEqual(secret, expected) { - t.Fatalf("bad: %#v %#v", secret, expected) + t.Fatalf("bad:\ngot\n%#v\nexpected\n%#v\n", secret, expected) } } diff --git a/audit/format_json.go b/audit/format_json.go index ebc41b1fa4..007113553f 100644 --- a/audit/format_json.go +++ b/audit/format_json.go @@ -176,9 +176,9 @@ type JSONSecret struct { } type JSONWrapInfo struct { - TTL int `json:"ttl"` - Token string `json:"token"` - CreationTime int64 `json:"creation_time"` + TTL int `json:"ttl"` + Token string `json:"token"` + CreationTime time.Time `json:"creation_time"` } // getRemoteAddr safely gets the remote address avoiding a nil pointer diff --git a/audit/hashstructure_test.go b/audit/hashstructure_test.go index 97d1b38fcb..eb3f9208f8 100644 --- a/audit/hashstructure_test.go +++ b/audit/hashstructure_test.go @@ -70,7 +70,7 @@ func TestCopy_response(t *testing.T) { WrapInfo: &logical.WrapInfo{ TTL: 60, Token: "foo", - CreationTime: 100000, + CreationTime: time.Now(), }, } arg := expected @@ -140,7 +140,7 @@ func TestHash(t *testing.T) { WrapInfo: &logical.WrapInfo{ TTL: 60, Token: "bar", - CreationTime: 100000, + CreationTime: now, }, }, &logical.Response{ @@ -150,7 +150,7 @@ func TestHash(t *testing.T) { WrapInfo: &logical.WrapInfo{ TTL: 60, Token: "hmac-sha256:f9320baf0249169e73850cd6156ded0106e2bb6ad8cab01b7bbbebe6d1065317", - CreationTime: 100000, + CreationTime: now, }, }, }, diff --git a/command/format.go b/command/format.go index 9c617e5c07..8f9883e4f1 100644 --- a/command/format.go +++ b/command/format.go @@ -160,7 +160,7 @@ func (t TableFormatter) OutputSecret(ui cli.Ui, secret, s *api.Secret) error { if s.WrapInfo != nil { input = append(input, fmt.Sprintf("wrapping_token: %s %s", config.Delim, s.WrapInfo.Token)) input = append(input, fmt.Sprintf("wrapping_token_ttl: %s %d", config.Delim, s.WrapInfo.TTL)) - input = append(input, fmt.Sprintf("wrapping_token_creation_time: %s %d", config.Delim, s.WrapInfo.CreationTime)) + input = append(input, fmt.Sprintf("wrapping_token_creation_time: %s %s", config.Delim, s.WrapInfo.CreationTime.String())) } keys := make([]string, 0, len(s.Data)) diff --git a/command/util.go b/command/util.go index ec4897d0ef..6666bc2fd8 100644 --- a/command/util.go +++ b/command/util.go @@ -42,7 +42,7 @@ func PrintRawField(ui cli.Ui, secret *api.Secret, field string) int { } case "wrapping_token_creation_time": if secret.WrapInfo != nil { - val = secret.WrapInfo.CreationTime + val = secret.WrapInfo.CreationTime.String() } case "refresh_interval": val = secret.LeaseDuration diff --git a/logical/response.go b/logical/response.go index 6175810104..0e53802e09 100644 --- a/logical/response.go +++ b/logical/response.go @@ -35,9 +35,9 @@ type WrapInfo struct { // The token containing the wrapped response Token string - // The creation time in seconds since Unix epoch. This can be used with the - // TTL to figure out an expected expiration. - CreationTime int64 + // The creation time. This can be used with the TTL to figure out an + // expected expiration. + CreationTime time.Time } // Response is a struct that stores the response of a request. diff --git a/logical/sanitize.go b/logical/sanitize.go index 5a7086ddd0..7607990283 100644 --- a/logical/sanitize.go +++ b/logical/sanitize.go @@ -1,5 +1,7 @@ package logical +import "time" + // This logic was pulled from the http package so that it can be used for // encoding wrapped responses as well. It simply translates the logical request // to an http response, with the values we want and omitting the values we @@ -52,7 +54,7 @@ type HTTPAuth struct { } type HTTPWrapInfo struct { - Token string `json:"token"` - TTL int `json:"ttl"` - CreationTime int64 `json:"creation_time"` + Token string `json:"token"` + TTL int `json:"ttl"` + CreationTime time.Time `json:"creation_time"` } diff --git a/vault/request_handling.go b/vault/request_handling.go index 75386b3500..9a92fa85cc 100644 --- a/vault/request_handling.go +++ b/vault/request_handling.go @@ -375,10 +375,11 @@ func (c *Core) wrapInCubbyhole(req *logical.Request, resp *logical.Response) (*l // before auditing so that resp.WrapInfo.Token can contain the HMAC'd // 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{ Path: req.Path, Policies: []string{"cubbyhole-response-wrapping"}, - CreationTime: time.Now().Unix(), + CreationTime: creationTime.Unix(), TTL: resp.WrapInfo.TTL, NumUses: 1, ExplicitMaxTTL: resp.WrapInfo.TTL, @@ -390,7 +391,7 @@ func (c *Core) wrapInCubbyhole(req *logical.Request, resp *logical.Response) (*l } resp.WrapInfo.Token = te.ID - resp.WrapInfo.CreationTime = te.CreationTime + resp.WrapInfo.CreationTime = creationTime httpResponse := logical.SanitizeResponse(resp)