-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathvanta.go
110 lines (88 loc) · 2.54 KB
/
vanta.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
108
109
110
package vanta
import (
"bytes"
"encoding/json"
"net/http"
"strings"
"time"
"github.com/superfly/ssokenizer"
"github.com/superfly/ssokenizer/oauth2"
"github.com/superfly/tokenizer"
xoauth2 "golang.org/x/oauth2"
)
const (
invalidatePath = "/invalidate"
invalidateURL = "https://api.vanta.com/v1/oauth/token/suspend"
)
type Config oauth2.Config
func (c Config) Register(sealKey string, auth tokenizer.AuthConfig) (http.Handler, error) {
handler, err := oauth2.Config(c).Register(sealKey, auth)
if err != nil {
return nil, err
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.TrimSuffix(r.URL.Path, "/") != invalidatePath {
handler.ServeHTTP(w, r)
return
}
var (
ctx = r.Context()
log = ssokenizer.GetLog(r)
)
accessToken, ok := strings.CutPrefix(r.Header.Get("Authorization"), "Bearer ")
if !ok {
log.WithField("status", http.StatusUnauthorized).
Info("invalidate: missing token")
w.WriteHeader(http.StatusUnauthorized)
return
}
tok, err := c.TokenSource(ctx, &xoauth2.Token{AccessToken: accessToken}).Token()
if err != nil {
log.WithField("status", http.StatusForbidden).
WithError(err).
Info("invalidate: failed to get token")
w.WriteHeader(http.StatusForbidden)
return
}
if typ := tok.Type(); typ != "Bearer" {
log.WithField("status", http.StatusForbidden).
WithField("type", typ).
WithError(err).
Info("invalidate: bad token type")
w.WriteHeader(http.StatusForbidden)
return
}
body, err := json.Marshal(map[string]string{
"token": tok.AccessToken,
"client_id": c.ClientID,
"client_secret": c.ClientSecret,
})
if err != nil {
log.WithField("status", http.StatusInternalServerError).
WithError(err).
Info("invalidate: marshal json")
w.WriteHeader(http.StatusInternalServerError)
return
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, invalidateURL, bytes.NewBuffer(body))
if err != nil {
log.WithField("status", http.StatusInternalServerError).
WithError(err).
Info("invalidate: make request")
w.WriteHeader(http.StatusInternalServerError)
return
}
req.Header.Set("Content-Type", "application/json")
client := http.Client{Timeout: 10 * time.Second}
resp, err := client.Do(req)
if err != nil {
log.WithField("status", http.StatusServiceUnavailable).
WithError(err).
Info("invalidate: send request")
w.WriteHeader(http.StatusServiceUnavailable)
return
}
log.WithField("status", resp.Status).
Info("invalidate: success")
}), nil
}