-
Notifications
You must be signed in to change notification settings - Fork 2
/
middleware.go
98 lines (79 loc) · 2.15 KB
/
middleware.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package autohttp
import (
"errors"
"net/http"
"github.com/fortytw2/autohttp/internal/keysigner"
)
// Middleware is used for things such as authentication / authorization controls
// checking specific headers of a request
// etc
type Middleware interface {
// Before can modify an incoming request in the middleware chain
Before(r *http.Request, h *Handler) error
}
type MiddlewareError struct {
StatusCode int
Err error
}
func (mwe MiddlewareError) Error() string {
return mwe.Err.Error()
}
// SignedHeadersMiddleware validates that all incoming headers are signed using a certain key
// if they're set as a header outgoing, they'll also be signed on the way out.
// this works great for cookies and the like
type SignedHeadersMiddleware struct {
ks *keysigner.KeySigner
headers []string
}
func NewSignedHeadersMiddleware(headers []string, key string) *SignedHeadersMiddleware {
ks := keysigner.NewKeySigner(key)
return &SignedHeadersMiddleware{
headers: headers,
ks: ks,
}
}
func (shm *SignedHeadersMiddleware) Before(r *http.Request, h *Handler) error {
for _, h := range shm.headers {
hVal := r.Header.Get(h)
verified, err := shm.ks.Verify(hVal)
if err != nil {
return MiddlewareError{
StatusCode: http.StatusForbidden,
Err: err,
}
}
r.Header.Set(h, verified)
}
return nil
}
func (shm *SignedHeadersMiddleware) Verify(value string) (string, error) {
return shm.ks.Verify((value))
}
func (shm *SignedHeadersMiddleware) Sign(value string) (string, error) {
return shm.ks.Sign((value))
}
type BasicAuthMiddleware struct {
username, password string
}
func NewBasicAuthMiddleware(user, pwd string) *BasicAuthMiddleware {
return &BasicAuthMiddleware{
username: user,
password: pwd,
}
}
func (bam *BasicAuthMiddleware) Before(r *http.Request, h *Handler) error {
uname, pwd, ok := r.BasicAuth()
if !ok {
return MiddlewareError{
StatusCode: http.StatusForbidden,
Err: errors.New("basic auth required"),
}
}
if bam.username != uname || bam.password != pwd {
return MiddlewareError{
StatusCode: http.StatusForbidden,
Err: errors.New("invalid basic auth"),
}
}
return nil
}