Skip to content

Commit

Permalink
Maxchehab/ch1327/go implement idempotency key header for audit (#24)
Browse files Browse the repository at this point in the history
* feat: only attach key if value is not empty

* update: idempotency key documentation

* fix: test so that they pass.

* fix idempotency key json

* fix idempotency key empty check
  • Loading branch information
maxchehab authored Jan 31, 2020
1 parent 98b8097 commit aa64bce
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 33 deletions.
16 changes: 4 additions & 12 deletions pkg/auditlog/auditlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ import (
"fmt"
"os"
"time"

"github.com/google/uuid"
)

var (
Expand Down Expand Up @@ -63,11 +61,12 @@ type Event struct {
ActorID string `json:"actor_id"`
Group string `json:"group"`

// A key that ensures that an same event is not processed multiple time.
// A key that ensures that the same event is not processed multiple times.
// Once the event is sent for the first time, the lock on the key expires
// after 24 hours.
//
// An idempotency key is automatically generated if not set.

// If no key is provided or the key is empty, the key will not be attached
// to the request.
IdempotencyKey string `json:"-"`

// An ip address that locates where the audit log occurred.
Expand Down Expand Up @@ -131,10 +130,3 @@ func defaultTime(t time.Time) time.Time {
}
return t
}

func defaultIdempotencyKey(key string) string {
if key == "" {
return uuid.New().String()
}
return key
}
6 changes: 4 additions & 2 deletions pkg/auditlog/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ func (c *Client) Publish(ctx context.Context, e Event) error {
return err
}

e.IdempotencyKey = defaultIdempotencyKey(e.IdempotencyKey)
e.OccurredAt = defaultTime(e.OccurredAt)

data, err := c.JSONEncode(e)
Expand All @@ -67,9 +66,12 @@ func (c *Client) Publish(ctx context.Context, e Event) error {
}
req = req.WithContext(ctx)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", e.IdempotencyKey)
req.Header.Set("Authorization", "Bearer "+c.APIKey)

if e.IdempotencyKey != "" {
req.Header.Set("Idempotency-Key", e.IdempotencyKey)
}

res, err := c.HTTPClient.Do(req)
if err != nil {
return err
Expand Down
26 changes: 7 additions & 19 deletions pkg/auditlog/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,30 +95,18 @@ func (h *defaultTestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}

requiredHeaders := map[string]string{
"Content-Type": "application/json",
"Idempotency-Key": "test",
"Authorization": "Bearer test",
"Content-Type": "application/json",
"Authorization": "Bearer test",
}

for k, v := range requiredHeaders {
val := r.Header.Get(k)

switch k {
case "Idempotency-Key":
if val == "" {
h.errors++
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("no indempotency key found"))
return
}

default:
if val != v {
h.errors++
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("bad header value for " + k))
return
}
if val != v {
h.errors++
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("bad header value for " + k))
return
}
}

Expand Down

0 comments on commit aa64bce

Please sign in to comment.