open-vault/audit/format_json.go

194 lines
4.7 KiB
Go
Raw Normal View History

2015-04-13 21:12:03 +00:00
package audit
import (
"encoding/json"
"io"
2015-08-05 13:47:39 +00:00
"time"
2015-04-13 21:12:03 +00:00
"github.com/hashicorp/vault/logical"
)
// FormatJSON is a Formatter implementation that structures data into
2015-04-13 21:12:03 +00:00
// a JSON format.
type FormatJSON struct{}
func (f *FormatJSON) FormatRequest(
w io.Writer,
auth *logical.Auth,
req *logical.Request,
err error) error {
2015-04-13 21:12:03 +00:00
// If auth is nil, make an empty one
if auth == nil {
auth = new(logical.Auth)
}
var errString string
if err != nil {
errString = err.Error()
}
2015-04-13 21:12:03 +00:00
// Encode!
enc := json.NewEncoder(w)
return enc.Encode(&JSONRequestEntry{
2015-08-05 13:47:39 +00:00
Time: time.Now().UTC().Format(time.RFC3339),
Type: "request",
Error: errString,
2015-04-20 05:43:39 +00:00
2015-04-13 21:12:03 +00:00
Auth: JSONAuth{
DisplayName: auth.DisplayName,
Policies: auth.Policies,
Metadata: auth.Metadata,
2015-04-13 21:12:03 +00:00
},
Request: JSONRequest{
ClientToken: req.ClientToken,
Operation: req.Operation,
Path: req.Path,
Data: req.Data,
RemoteAddr: getRemoteAddr(req),
WrapTTL: int(req.WrapTTL / time.Second),
2015-04-13 21:12:03 +00:00
},
})
}
func (f *FormatJSON) FormatResponse(
w io.Writer,
auth *logical.Auth,
req *logical.Request,
resp *logical.Response,
err error) error {
// If things are nil, make empty to avoid panics
if auth == nil {
auth = new(logical.Auth)
}
if resp == nil {
resp = new(logical.Response)
}
var errString string
if err != nil {
errString = err.Error()
}
2015-04-13 21:12:03 +00:00
var respAuth *JSONAuth
2015-04-13 21:12:03 +00:00
if resp.Auth != nil {
respAuth = &JSONAuth{
2015-04-13 21:12:03 +00:00
ClientToken: resp.Auth.ClientToken,
Accessor: resp.Auth.Accessor,
DisplayName: resp.Auth.DisplayName,
2015-04-13 21:12:03 +00:00
Policies: resp.Auth.Policies,
Metadata: resp.Auth.Metadata,
}
}
var respSecret *JSONSecret
2015-04-13 21:12:03 +00:00
if resp.Secret != nil {
respSecret = &JSONSecret{
2015-04-13 21:12:03 +00:00
LeaseID: resp.Secret.LeaseID,
}
}
2016-05-07 23:19:19 +00:00
var respWrapInfo *JSONWrapInfo
if resp.WrapInfo != nil {
respWrapInfo = &JSONWrapInfo{
TTL: int(resp.WrapInfo.TTL / time.Second),
Token: resp.WrapInfo.Token,
CreationTime: resp.WrapInfo.CreationTime,
WrappedAccessor: resp.WrapInfo.WrappedAccessor,
2016-05-07 23:19:19 +00:00
}
}
2015-04-13 21:12:03 +00:00
// Encode!
enc := json.NewEncoder(w)
return enc.Encode(&JSONResponseEntry{
2015-08-05 13:47:39 +00:00
Time: time.Now().UTC().Format(time.RFC3339),
Type: "response",
Error: errString,
2015-04-20 05:43:39 +00:00
2015-04-13 21:12:03 +00:00
Auth: JSONAuth{
DisplayName: auth.DisplayName,
Policies: auth.Policies,
Metadata: auth.Metadata,
2015-04-13 21:12:03 +00:00
},
Request: JSONRequest{
ClientToken: req.ClientToken,
Operation: req.Operation,
Path: req.Path,
Data: req.Data,
RemoteAddr: getRemoteAddr(req),
WrapTTL: int(req.WrapTTL / time.Second),
2015-04-13 21:12:03 +00:00
},
Response: JSONResponse{
Auth: respAuth,
Secret: respSecret,
Data: resp.Data,
Redirect: resp.Redirect,
2016-05-07 23:19:19 +00:00
WrapInfo: respWrapInfo,
2015-04-13 21:12:03 +00:00
},
})
}
// JSONRequest is the structure of a request audit log entry in JSON.
type JSONRequestEntry struct {
Time string `json:"time"`
Type string `json:"type"`
Auth JSONAuth `json:"auth"`
Request JSONRequest `json:"request"`
Error string `json:"error"`
2015-04-13 21:12:03 +00:00
}
// JSONResponseEntry is the structure of a response audit log entry in JSON.
type JSONResponseEntry struct {
2015-08-05 13:47:39 +00:00
Time string `json:"time"`
2015-04-20 05:43:39 +00:00
Type string `json:"type"`
2015-04-13 21:12:03 +00:00
Error string `json:"error"`
Auth JSONAuth `json:"auth"`
Request JSONRequest `json:"request"`
2015-04-20 05:43:39 +00:00
Response JSONResponse `json:"response"`
2015-04-13 21:12:03 +00:00
}
type JSONRequest struct {
Operation logical.Operation `json:"operation"`
ClientToken string `json:"client_token"`
Path string `json:"path"`
Data map[string]interface{} `json:"data"`
RemoteAddr string `json:"remote_address"`
WrapTTL int `json:"wrap_ttl"`
2015-04-13 21:12:03 +00:00
}
type JSONResponse struct {
Auth *JSONAuth `json:"auth,omitempty"`
Secret *JSONSecret `json:"secret,emitempty"`
2015-04-13 21:12:03 +00:00
Data map[string]interface{} `json:"data"`
Redirect string `json:"redirect"`
2016-05-07 23:19:19 +00:00
WrapInfo *JSONWrapInfo `json:"wrap_info,omitempty"`
2015-04-13 21:12:03 +00:00
}
type JSONAuth struct {
ClientToken string `json:"client_token,omitempty"`
Accessor string `json:"accessor,omitempty"`
DisplayName string `json:"display_name"`
2015-04-13 21:12:03 +00:00
Policies []string `json:"policies"`
Metadata map[string]string `json:"metadata"`
}
type JSONSecret struct {
LeaseID string `json:"lease_id"`
}
2016-05-07 23:19:19 +00:00
type JSONWrapInfo struct {
TTL int `json:"ttl"`
Token string `json:"token"`
CreationTime time.Time `json:"creation_time"`
WrappedAccessor string `json:"wrapped_accessor,omitempty"`
2016-05-07 23:19:19 +00:00
}
// getRemoteAddr safely gets the remote address avoiding a nil pointer
func getRemoteAddr(req *logical.Request) string {
if req != nil && req.Connection != nil {
return req.Connection.RemoteAddr
}
return ""
}