mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 11:08:10 +00:00
audit: JSON formatter
This commit is contained in:
126
audit/format_json.go
Normal file
126
audit/format_json.go
Normal file
@@ -0,0 +1,126 @@
|
||||
package audit
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/hashicorp/vault/logical"
|
||||
)
|
||||
|
||||
// FormatJSON is a Formatter implementation that structuteres data into
|
||||
// a JSON format.
|
||||
type FormatJSON struct{}
|
||||
|
||||
func (f *FormatJSON) FormatRequest(
|
||||
w io.Writer,
|
||||
auth *logical.Auth, req *logical.Request) error {
|
||||
// If auth is nil, make an empty one
|
||||
if auth == nil {
|
||||
auth = new(logical.Auth)
|
||||
}
|
||||
|
||||
// Encode!
|
||||
enc := json.NewEncoder(w)
|
||||
return enc.Encode(&JSONRequestEntry{
|
||||
Auth: JSONAuth{
|
||||
Policies: auth.Policies,
|
||||
Metadata: auth.Metadata,
|
||||
},
|
||||
|
||||
Request: JSONRequest{
|
||||
Operation: req.Operation,
|
||||
Path: req.Path,
|
||||
Data: req.Data,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
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 respAuth JSONAuth
|
||||
if resp.Auth != nil {
|
||||
respAuth = JSONAuth{
|
||||
ClientToken: resp.Auth.ClientToken,
|
||||
Policies: resp.Auth.Policies,
|
||||
Metadata: resp.Auth.Metadata,
|
||||
}
|
||||
}
|
||||
|
||||
var respSecret JSONSecret
|
||||
if resp.Secret != nil {
|
||||
respSecret = JSONSecret{
|
||||
LeaseID: resp.Secret.LeaseID,
|
||||
}
|
||||
}
|
||||
|
||||
// Encode!
|
||||
enc := json.NewEncoder(w)
|
||||
return enc.Encode(&JSONResponseEntry{
|
||||
Auth: JSONAuth{
|
||||
Policies: auth.Policies,
|
||||
Metadata: auth.Metadata,
|
||||
},
|
||||
|
||||
Request: JSONRequest{
|
||||
Operation: req.Operation,
|
||||
Path: req.Path,
|
||||
Data: req.Data,
|
||||
},
|
||||
|
||||
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 {
|
||||
Auth JSONAuth `json:"auth"`
|
||||
Request JSONRequest `json:"request"`
|
||||
}
|
||||
|
||||
// JSONResponseEntry is the structure of a response audit log entry in JSON.
|
||||
type JSONResponseEntry struct {
|
||||
Error string `json:"error"`
|
||||
Auth JSONAuth `json:"auth"`
|
||||
Request JSONRequest `json:"request"`
|
||||
Response JSONResponse `json:"request"`
|
||||
}
|
||||
|
||||
type JSONRequest struct {
|
||||
Operation logical.Operation `json:"operation"`
|
||||
Path string `json:"path"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
}
|
||||
|
||||
type JSONResponse struct {
|
||||
Auth JSONAuth `json:"auth,omitempty"`
|
||||
Secret JSONSecret `json:"secret,emitempty"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
Redirect string `json:"redirect"`
|
||||
}
|
||||
|
||||
type JSONAuth struct {
|
||||
ClientToken string `json:"string,omitempty"`
|
||||
Policies []string `json:"policies"`
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
}
|
||||
|
||||
type JSONSecret struct {
|
||||
LeaseID string `json:"lease_id"`
|
||||
}
|
||||
42
audit/format_json_test.go
Normal file
42
audit/format_json_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package audit
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/logical"
|
||||
)
|
||||
|
||||
func TestFormatJSON_formatRequest(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Auth *logical.Auth
|
||||
Req *logical.Request
|
||||
Result string
|
||||
}{
|
||||
"auth, request": {
|
||||
&logical.Auth{ClientToken: "foo", Policies: []string{"root"}},
|
||||
&logical.Request{
|
||||
Operation: logical.WriteOperation,
|
||||
Path: "/foo",
|
||||
},
|
||||
testFormatJSONReqBasicStr,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range cases {
|
||||
var buf bytes.Buffer
|
||||
var format FormatJSON
|
||||
if err := format.FormatRequest(&buf, tc.Auth, tc.Req); err != nil {
|
||||
t.Fatalf("bad: %s\nerr: %s", name, err)
|
||||
}
|
||||
|
||||
if buf.String() != tc.Result {
|
||||
t.Fatalf(
|
||||
"bad: %s\nResult:\n\n%s\n\nExpected:\n\n%s",
|
||||
name, buf.String(), tc.Result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const testFormatJSONReqBasicStr = `{"auth":{"policies":["root"],"metadata":null},"request":{"operation":"write","path":"/foo","data":null}}
|
||||
`
|
||||
15
audit/formatter.go
Normal file
15
audit/formatter.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package audit
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/hashicorp/vault/logical"
|
||||
)
|
||||
|
||||
// Formatter is an interface that is responsible for formating a
|
||||
// request/response into some format. Formatters write their output
|
||||
// to an io.Writer.
|
||||
type Formatter interface {
|
||||
FormatRequest(io.Writer, *logical.Auth, *logical.Request) error
|
||||
FormatResponse(io.Writer, *logical.Auth, *logical.Request, *logical.Response, error) error
|
||||
}
|
||||
Reference in New Issue
Block a user