Skip to content

Commit 9b244cf

Browse files
Juanita De La CuestaJuanita De La Cuesta
authored andcommitted
Functionality: Add first draft of the validator wrapper
1 parent 29552d9 commit 9b244cf

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

signature/signature.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package signature
2+
3+
import (
4+
"bytes"
5+
"crypto/hmac"
6+
"crypto/sha256"
7+
"encoding/base64"
8+
"fmt"
9+
"io/ioutil"
10+
"log"
11+
"net/http"
12+
"strconv"
13+
"time"
14+
)
15+
16+
func StringToTime(s string) (time.Time, error) {
17+
sec, err := strconv.ParseInt(s, 10, 64)
18+
if err != nil {
19+
return time.Time{}, err
20+
}
21+
return time.Unix(sec, 0), nil
22+
}
23+
24+
func HMACSHA256(message, signingKey []byte) ([]byte, error) {
25+
mac := hmac.New(sha256.New, []byte(signingKey))
26+
if _, err := mac.Write(message); err != nil {
27+
return nil, err
28+
}
29+
return mac.Sum(nil), nil
30+
}
31+
32+
type Validator struct {
33+
SigningKey string
34+
Period float64
35+
Log *log.Logger
36+
LogMesssage string
37+
}
38+
39+
func (v *Validator) ValidTimestamp(ts time.Time) bool {
40+
if v.Period != 0 {
41+
now := time.Now()
42+
if diff := now.Sub(ts); diff.Hours() > v.Period {
43+
return false
44+
}
45+
}
46+
return true
47+
}
48+
49+
func (v *Validator) CalculateSignature(ts, qp string, b []byte) ([]byte, error) {
50+
var m bytes.Buffer
51+
bh := sha256.Sum256(b)
52+
fmt.Fprintf(&m, "%s\n%s\n%s", ts, qp, bh[:])
53+
s, err := HMACSHA256(m.Bytes(), []byte(v.SigningKey))
54+
if err != nil {
55+
return nil, err
56+
}
57+
return s, nil
58+
}
59+
60+
func (v *Validator) ValidSignature(ts, qp, rs string, b []byte) bool {
61+
es, _ := v.CalculateSignature(ts, qp, b)
62+
drs, _ := base64.StdEncoding.DecodeString(rs)
63+
return hmac.Equal(drs, es)
64+
}
65+
66+
func (v *Validator) Wrapper(h http.Handler) http.Handler {
67+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
68+
ts := r.Header.Get("MessageBird-Request-Timestamp")
69+
rs := r.Header.Get("MessageBird-Request-Signature")
70+
if ts == "" || rs == "" {
71+
http.Error(w, "Request not allowed", http.StatusUnauthorized)
72+
return
73+
}
74+
t, _ := StringToTime(ts)
75+
b, _ := ioutil.ReadAll(r.Body)
76+
if v.ValidTimestamp(t) == false || v.ValidSignature(ts, r.URL.RawQuery, rs, b) == false {
77+
http.Error(w, "Request not allowed", http.StatusUnauthorized)
78+
return
79+
}
80+
h.ServeHTTP(w, r)
81+
})
82+
}

signature/signature_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package signature

0 commit comments

Comments
 (0)