forked from xmidt-org/caduceus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
primaryHandler.go
107 lines (85 loc) · 2.98 KB
/
primaryHandler.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
99
100
101
102
103
104
105
106
107
package main
import (
"fmt"
"net/http"
"github.com/SermoDigital/jose/jwt"
"github.com/go-kit/kit/log"
"github.com/gorilla/mux"
"github.com/justinas/alice"
"github.com/spf13/viper"
"github.com/xmidt-org/webpa-common/secure"
"github.com/xmidt-org/webpa-common/secure/handler"
"github.com/xmidt-org/webpa-common/secure/key"
"github.com/xmidt-org/webpa-common/webhook"
)
const (
baseURI = "api"
version = "v3"
)
type JWTValidator struct {
// JWTKeys is used to create the key.Resolver for JWT verification keys
Keys key.ResolverFactory
// Custom is an optional configuration section that defines
// custom rules for validation over and above the standard RFC rules.
Custom secure.JWTValidatorFactory
}
func NewPrimaryHandler(l log.Logger, v *viper.Viper, sw *ServerHandler, reg *webhook.Registry) (*mux.Router, error) {
var (
router = mux.NewRouter()
)
validator, err := getValidator(v)
if err != nil {
return nil, err
}
authHandler := handler.AuthorizationHandler{
HeaderName: "Authorization",
ForbiddenStatusCode: 403,
Validator: validator,
Logger: l,
}
authorizationDecorator := alice.New(authHandler.Decorate)
return configServerRouter(router, authorizationDecorator, sw, reg), nil
}
func configServerRouter(router *mux.Router, primaryHandler alice.Chain, serverWrapper *ServerHandler, webhookRegistry *webhook.Registry) *mux.Router {
var singleContentType = func(r *http.Request, _ *mux.RouteMatch) bool {
return len(r.Header["Content-Type"]) == 1 //require single specification for Content-Type Header
}
router.Handle("/"+fmt.Sprintf("%s/%s", baseURI, version)+"/notify", primaryHandler.Then(serverWrapper)).Methods("POST").HeadersRegexp("Content-Type", "application/msgpack").MatcherFunc(singleContentType)
// register webhook end points
router.Handle("/hook", primaryHandler.ThenFunc(webhookRegistry.UpdateRegistry)).Methods("POST")
router.Handle("/hooks", primaryHandler.ThenFunc(webhookRegistry.GetRegistry)).Methods("GET")
return router
}
func getValidator(v *viper.Viper) (validator secure.Validator, err error) {
var jwtVals []JWTValidator
v.UnmarshalKey("jwtValidators", &jwtVals)
// if a JWTKeys section was supplied, configure a JWS validator
// and append it to the chain of validators
validators := make(secure.Validators, 0, len(jwtVals))
for _, validatorDescriptor := range jwtVals {
var keyResolver key.Resolver
keyResolver, err = validatorDescriptor.Keys.NewResolver()
if err != nil {
validator = validators
return
}
validators = append(
validators,
secure.JWSValidator{
DefaultKeyId: DEFAULT_KEY_ID,
Resolver: keyResolver,
JWTValidators: []*jwt.Validator{validatorDescriptor.Custom.New()},
},
)
}
// TODO: This should really be part of the unmarshalled validators somehow
basicAuth := v.GetStringSlice("authHeader")
for _, authValue := range basicAuth {
validators = append(
validators,
secure.ExactMatchValidator(authValue),
)
}
validator = validators
return
}