|
7 | 7 | "encoding/base64"
|
8 | 8 | "fmt"
|
9 | 9 | "io/ioutil"
|
10 |
| - "log" |
11 | 10 | "math"
|
12 | 11 | "net/http"
|
13 | 12 | "net/url"
|
@@ -42,19 +41,15 @@ func hMACSHA256(message, key []byte) ([]byte, error) {
|
42 | 41 |
|
43 | 42 | // Validator type represents a MessageBird signature validator
|
44 | 43 | type Validator struct {
|
45 |
| - SigningKey string // Signing Key provided by MessageBird |
46 |
| - Period ValidityPeriod // Period in hours for a message to be accepted as real, set to nil to bypass the timestamp validator |
47 |
| - Log *log.Logger |
48 |
| - LogMesssage *string |
| 44 | + SigningKey string // Signing Key provided by MessageBird |
| 45 | + Period ValidityPeriod // Period in hours for a message to be accepted as real, set to nil to bypass the timestamp validator |
49 | 46 | }
|
50 | 47 |
|
51 | 48 | // NewValidator returns a signature validator object
|
52 |
| -func NewValidator(signingKey string, period ValidityPeriod, log *log.Logger, message *string) *Validator { |
| 49 | +func NewValidator(signingKey string, period ValidityPeriod) *Validator { |
53 | 50 | return &Validator{
|
54 |
| - SigningKey: signingKey, |
55 |
| - Period: period, |
56 |
| - Log: log, |
57 |
| - LogMesssage: message, |
| 51 | + SigningKey: signingKey, |
| 52 | + Period: period, |
58 | 53 | }
|
59 | 54 | }
|
60 | 55 |
|
@@ -110,29 +105,36 @@ func (v *Validator) ValidSignature(ts, rqp string, b []byte, rs string) bool {
|
110 | 105 | }
|
111 | 106 |
|
112 | 107 | func (v *Validator) Error(w http.ResponseWriter, r *http.Request) {
|
113 |
| - if v.Log != nil { |
114 |
| - v.Log.Printf("%s, sending host: %s", *v.LogMesssage, r.Host) |
| 108 | + |
| 109 | +} |
| 110 | + |
| 111 | +// ValidRequest is a method that takes care of the signature validation of |
| 112 | +// incoming requests |
| 113 | +// To use just wrap your handler with it: |
| 114 | +// signature.Validate(request) |
| 115 | +func (v *Validator) ValidRequest(r *http.Request) (bool, error) { |
| 116 | + ts := r.Header.Get(tsHeader) |
| 117 | + rs := r.Header.Get(sHeader) |
| 118 | + if ts == "" || rs == "" { |
| 119 | + return false, fmt.Errorf("Unknown host: %s", r.Host) |
115 | 120 | }
|
116 |
| - http.Error(w, "Request not allowed", http.StatusUnauthorized) |
117 |
| - return |
| 121 | + b, _ := ioutil.ReadAll(r.Body) |
| 122 | + if v.ValidTimestamp(ts) == false || v.ValidSignature(ts, r.URL.RawQuery, b, rs) == false { |
| 123 | + return false, fmt.Errorf("Unknown host: %s", r.Host) |
| 124 | + } |
| 125 | + r.Body = ioutil.NopCloser(bytes.NewBuffer(b)) |
| 126 | + return true, nil |
118 | 127 | }
|
119 | 128 |
|
120 | 129 | // Validate is a handler wrapper that takes care of the signature validation of
|
121 | 130 | // incoming requests and rejects them if invalid or pass them on to your handler
|
122 | 131 | // otherwise.
|
123 |
| -// To use just wrappe your handler with it: |
| 132 | +// To use just wrap your handler with it: |
124 | 133 | // http.Handle("/path", signature.Validate(handleThing))
|
125 | 134 | func (v *Validator) Validate(h http.Handler) http.Handler {
|
126 | 135 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
127 |
| - ts := r.Header.Get(tsHeader) |
128 |
| - rs := r.Header.Get(sHeader) |
129 |
| - if ts == "" || rs == "" { |
130 |
| - v.Error(w, r) |
131 |
| - return |
132 |
| - } |
133 |
| - b, _ := ioutil.ReadAll(r.Body) |
134 |
| - if v.ValidTimestamp(ts) == false || v.ValidSignature(ts, r.URL.RawQuery, b, rs) == false { |
135 |
| - v.Error(w, r) |
| 136 | + if res, _ := v.ValidRequest(r); res == false { |
| 137 | + http.Error(w, "", http.StatusUnauthorized) |
136 | 138 | return
|
137 | 139 | }
|
138 | 140 | h.ServeHTTP(w, r)
|
|
0 commit comments