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"
|
|
|
|
)
|
|
|
|
|
2015-06-19 01:30:18 +00:00
|
|
|
// 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,
|
2015-06-19 01:30:18 +00:00
|
|
|
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)
|
|
|
|
}
|
2015-06-29 22:27:28 +00:00
|
|
|
var errString string
|
|
|
|
if err != nil {
|
|
|
|
errString = err.Error()
|
2015-06-19 01:30:18 +00:00
|
|
|
}
|
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),
|
2015-06-29 22:27:28 +00:00
|
|
|
Type: "request",
|
|
|
|
Error: errString,
|
2015-04-20 05:43:39 +00:00
|
|
|
|
2015-04-13 21:12:03 +00:00
|
|
|
Auth: JSONAuth{
|
2015-05-11 17:40:32 +00:00
|
|
|
DisplayName: auth.DisplayName,
|
|
|
|
Policies: auth.Policies,
|
|
|
|
Metadata: auth.Metadata,
|
2015-04-13 21:12:03 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
Request: JSONRequest{
|
2015-10-29 17:24:30 +00:00
|
|
|
ClientToken: req.ClientToken,
|
|
|
|
Operation: req.Operation,
|
|
|
|
Path: req.Path,
|
|
|
|
Data: req.Data,
|
|
|
|
RemoteAddr: getRemoteAddr(req),
|
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)
|
|
|
|
}
|
2015-06-29 22:27:28 +00:00
|
|
|
var errString string
|
|
|
|
if err != nil {
|
|
|
|
errString = err.Error()
|
2015-06-19 00:17:18 +00:00
|
|
|
}
|
2015-04-13 21:12:03 +00:00
|
|
|
|
2015-06-19 02:48:00 +00:00
|
|
|
var respAuth *JSONAuth
|
2015-04-13 21:12:03 +00:00
|
|
|
if resp.Auth != nil {
|
2015-06-19 02:48:00 +00:00
|
|
|
respAuth = &JSONAuth{
|
2015-04-13 21:12:03 +00:00
|
|
|
ClientToken: resp.Auth.ClientToken,
|
2016-03-09 21:18:36 +00:00
|
|
|
Accessor: resp.Auth.Accessor,
|
2015-05-11 17:40:32 +00:00
|
|
|
DisplayName: resp.Auth.DisplayName,
|
2015-04-13 21:12:03 +00:00
|
|
|
Policies: resp.Auth.Policies,
|
|
|
|
Metadata: resp.Auth.Metadata,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-19 02:48:00 +00:00
|
|
|
var respSecret *JSONSecret
|
2015-04-13 21:12:03 +00:00
|
|
|
if resp.Secret != nil {
|
2015-06-19 02:48:00 +00:00
|
|
|
respSecret = &JSONSecret{
|
2015-04-13 21:12:03 +00:00
|
|
|
LeaseID: resp.Secret.LeaseID,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Encode!
|
|
|
|
enc := json.NewEncoder(w)
|
|
|
|
return enc.Encode(&JSONResponseEntry{
|
2015-08-05 13:47:39 +00:00
|
|
|
Time: time.Now().UTC().Format(time.RFC3339),
|
2015-06-29 22:27:28 +00:00
|
|
|
Type: "response",
|
|
|
|
Error: errString,
|
2015-04-20 05:43:39 +00:00
|
|
|
|
2015-04-13 21:12:03 +00:00
|
|
|
Auth: JSONAuth{
|
|
|
|
Policies: auth.Policies,
|
|
|
|
Metadata: auth.Metadata,
|
|
|
|
},
|
|
|
|
|
|
|
|
Request: JSONRequest{
|
2015-06-19 00:17:18 +00:00
|
|
|
Operation: req.Operation,
|
|
|
|
Path: req.Path,
|
|
|
|
Data: req.Data,
|
2015-06-29 22:27:28 +00:00
|
|
|
RemoteAddr: getRemoteAddr(req),
|
2015-04-13 21:12:03 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
Response: JSONResponse{
|
|
|
|
Auth: respAuth,
|
|
|
|
Secret: respSecret,
|
|
|
|
Data: resp.Data,
|
|
|
|
Redirect: resp.Redirect,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// JSONRequest is the structure of a request audit log entry in JSON.
|
|
|
|
type JSONRequestEntry struct {
|
2015-10-29 17:24:30 +00:00
|
|
|
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 {
|
2015-10-29 17:24:30 +00:00
|
|
|
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"`
|
2015-04-13 21:12:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type JSONResponse struct {
|
2015-06-29 22:27:28 +00:00
|
|
|
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"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type JSONAuth struct {
|
2015-05-11 17:40:32 +00:00
|
|
|
ClientToken string `json:"client_token,omitempty"`
|
2016-03-09 21:18:36 +00:00
|
|
|
Accessor string `json:"accessor,omitempty"`
|
2015-05-11 17:40:32 +00:00
|
|
|
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"`
|
|
|
|
}
|
2015-06-29 22:27:28 +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 ""
|
|
|
|
}
|