Skip to content

Commit

Permalink
Remove defer (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
RobbieMcKinstry authored and Robbie McKinstry committed May 10, 2018
1 parent b1456f5 commit de8c3af
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 7 deletions.
11 changes: 4 additions & 7 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,12 +364,6 @@ func NewClient(c *Config) (*Client, error) {
c = def
}

// Check to see if the Limiter has been set.
// If is has not been set, then set it to have no limit.
if c.Limiter == nil {
c.Limiter = rate.NewLimiter(rate.Inf, 0)
}

c.modifyLock.Lock()
defer c.modifyLock.Unlock()

Expand Down Expand Up @@ -596,7 +590,10 @@ func (c *Client) NewRequest(method, requestPath string) *Request {
// a Vault server not configured with this client. This is an advanced operation
// that generally won't need to be called externally.
func (c *Client) RawRequest(r *Request) (*Response, error) {
defer c.config.Limiter.Wait(context.Background())
if c.config.Limiter != nil {
c.config.Limiter.Wait(context.Background())
}

c.modifyLock.RLock()
c.config.modifyLock.RLock()
defer c.config.modifyLock.RUnlock()
Expand Down
155 changes: 155 additions & 0 deletions builtin/audit/advisor/backend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package advisor

import (
"bytes"
"context"
"errors"
"net/http"
"sync"

"github.com/hashicorp/vault/audit"
"github.com/hashicorp/vault/helper/salt"
)

// An Backend is an audit backend designed to
// communicate with an Advisor server over HTTP
type Backend struct {
address string
formatter *audit.AuditFormatter
config audit.FormatterConfig
salt *salt.Salt
saltMutex sync.RWMutex
}

var _ audit.Backend = &Backend{}

// LogRequest will serialize a Vault *Request into a JSON object
// and send that payload to Advisor over HTTP
func (backend *Backend) LogRequest(ctx context.Context, in *audit.LogInput) error {

var reqBody bytes.Buffer

err := backend.formatter.FormatRequest(ctx, &reqBody, backend.config, in)
if err != nil {
return err
}

httpResp, err := http.Post(backend.address, "application/json", &reqBody)
if err != nil {
return err
}
if httpResp.StatusCode < 200 || httpResp.StatusCode > 300 {
return errors.New("request to backend failed")
}
return nil
}

// LogResponse will serialize a Vault *Request into a JSON object
// and send that payload to Advisor over HTTP
func (backend *Backend) LogResponse(ctx context.Context, in *audit.LogInput) error {

var reqBody bytes.Buffer

err := backend.formatter.FormatResponse(ctx, &reqBody, backend.config, in)
if err != nil {
return err
}

httpResp, err := http.Post(backend.address, "application/json", &reqBody)
if err != nil {
return err
}
if httpResp.StatusCode < 200 || httpResp.StatusCode > 300 {
return errors.New("request to backend failed")
}
return nil
}

func (backend *Backend) setDefaultConfig() {
backend.config = audit.FormatterConfig{}
}

func (backend *Backend) setDefaultFormatter() {
backend.formatter = &audit.AuditFormatter{
AuditFormatWriter: &audit.JSONFormatWriter{
Prefix: "",
SaltFunc: backend.Salt,
},
}
}

// Pulls the address out of the configuration
func addressFromConfig(conf *audit.BackendConfig) (string, error) {
if addr, ok := conf.Config["address"]; ok {
return addr, nil
}

if addr, ok := conf.Config["a"]; ok {
return addr, nil
}

return "", errors.New("no address provided")
}

// Factory returns a new Advisor audit backend
func Factory(ctx context.Context, a *audit.BackendConfig) (audit.Backend, error) {
// First, create a new formatter for serializing
// requests and responses into JSON
advisor := &Backend{}
advisor.setDefaultFormatter()
advisor.setDefaultConfig()

// Next, collect the address from the configuration
addr, err := addressFromConfig(a)
if err != nil {
return nil, err
}

// Store the address on the new Backend struct.
advisor.address = addr

return advisor, nil
}

// Salt returns the salt singleton for this
// backend instance
func (backend *Backend) Salt(ctx context.Context) (*salt.Salt, error) {
backend.saltMutex.RLock()
if backend.salt != nil {
defer backend.saltMutex.RUnlock()
return backend.salt, nil
}
backend.saltMutex.RUnlock()
backend.saltMutex.Lock()
defer backend.saltMutex.Unlock()
if backend.salt != nil {
return backend.salt, nil
}
salt, err := salt.NewSalt(context.Background(), nil, nil)
if err != nil {
return nil, err
}
backend.salt = salt
return salt, nil
}

// GetHash is needed to implement the AuditBackend interface
func (backend *Backend) GetHash(ctx context.Context, data string) (string, error) {
salt, err := backend.Salt(ctx)
if err != nil {
return "", err
}
return salt.GetIdentifiedHMAC(data), nil
}

// Reload is required to implement the AuditBackend interface
func (backend *Backend) Reload(ctx context.Context) error {
return nil
}

// Invalidate is needed to implement the AuditBackend interface
func (backend *Backend) Invalidate(ctx context.Context) {
backend.saltMutex.Lock()
defer backend.saltMutex.Unlock()
backend.salt = nil
}

0 comments on commit de8c3af

Please sign in to comment.