/
adapter.go
107 lines (86 loc) · 2.61 KB
/
adapter.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 interfaces
import (
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
"time"
"github.com/Tinker-Ware/gh-service/domain"
"github.com/dvsekhvalnov/jose2go"
)
// Adapter is the signature of an HTTPHandler for middlewares
type Adapter func(http.Handler) http.Handler
type repository interface {
SetToken(token string)
}
// Notify is a middleware to measure the time that a request takes
func Notify() Adapter {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
defer log.Printf("%s on %s took %s\n", r.Method, r.URL.Path, time.Since(start))
h.ServeHTTP(w, r)
})
}
}
// Adapt takes several Adapters and calls them in order
func Adapt(h http.Handler, adapters ...Adapter) http.Handler {
for _, adapter := range adapters {
h = adapter(h)
}
return h
}
// SetToken injects the token from the request
func SetToken(repo repository) Adapter {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get(domain.TokenHeader)
repo.SetToken(token)
h.ServeHTTP(w, r)
})
}
}
type integration struct {
UserID int `json:"user_id"`
Token string `json:"token"`
Username string `json:"username"`
Provider string `json:"provider"`
ExpireDate int64 `json:"expire_date"`
}
type integrationsWrapper struct {
Integrations []integration `json:"integrations"`
}
const integrationsURL string = "/api/v1/users/%s/integration"
// GetToken gets the token from the users microservice
func GetToken(repo repository, apiURL string, salt string) Adapter {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
userToken := r.Header.Get("authorization")
sp := strings.Split(userToken, " ")
payload, _, _ := jose.Decode(sp[1], []byte(salt))
var objmap map[string]*json.RawMessage
json.Unmarshal([]byte(payload), &objmap)
var aud string
json.Unmarshal(*objmap["aud"], &aud)
vals := strings.Split(aud, ":")
path := fmt.Sprintf(integrationsURL, vals[1])
request, _ := http.NewRequest(http.MethodGet, apiURL+path, nil)
request.Header.Set("authorization", userToken)
client := &http.Client{}
resp, _ := client.Do(request)
defer resp.Body.Close()
integrations := integrationsWrapper{}
decoder := json.NewDecoder(resp.Body)
decoder.Decode(&integrations)
var token string
for _, integ := range integrations.Integrations {
if integ.Provider == "github" {
token = integ.Token
}
}
repo.SetToken(token)
h.ServeHTTP(w, r)
})
}
}