...
1 package ghinstallation
2
3 import (
4 "crypto/rsa"
5 "fmt"
6 "io/ioutil"
7 "net/http"
8 "strconv"
9 "time"
10
11 jwt "github.com/golang-jwt/jwt/v4"
12 )
13
14
15
16
17
18
19
20
21
22 type AppsTransport struct {
23 BaseURL string
24 Client Client
25 tr http.RoundTripper
26 key *rsa.PrivateKey
27 appID int64
28 }
29
30
31 func NewAppsTransportKeyFromFile(tr http.RoundTripper, appID int64, privateKeyFile string) (*AppsTransport, error) {
32 privateKey, err := ioutil.ReadFile(privateKeyFile)
33 if err != nil {
34 return nil, fmt.Errorf("could not read private key: %s", err)
35 }
36 return NewAppsTransport(tr, appID, privateKey)
37 }
38
39
40
41
42
43
44
45
46 func NewAppsTransport(tr http.RoundTripper, appID int64, privateKey []byte) (*AppsTransport, error) {
47 key, err := jwt.ParseRSAPrivateKeyFromPEM(privateKey)
48 if err != nil {
49 return nil, fmt.Errorf("could not parse private key: %s", err)
50 }
51 return NewAppsTransportFromPrivateKey(tr, appID, key), nil
52 }
53
54
55 func NewAppsTransportFromPrivateKey(tr http.RoundTripper, appID int64, key *rsa.PrivateKey) *AppsTransport {
56 return &AppsTransport{
57 BaseURL: apiBaseURL,
58 Client: &http.Client{Transport: tr},
59 tr: tr,
60 key: key,
61 appID: appID,
62 }
63 }
64
65
66 func (t *AppsTransport) RoundTrip(req *http.Request) (*http.Response, error) {
67
68
69
70 iss := time.Now().Add(-30 * time.Second).Truncate(time.Second)
71 exp := iss.Add(2 * time.Minute)
72 claims := &jwt.StandardClaims{
73 IssuedAt: iss.Unix(),
74 ExpiresAt: exp.Unix(),
75 Issuer: strconv.FormatInt(t.appID, 10),
76 }
77 bearer := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
78
79 ss, err := bearer.SignedString(t.key)
80 if err != nil {
81 return nil, fmt.Errorf("could not sign jwt: %s", err)
82 }
83
84 req.Header.Set("Authorization", "Bearer "+ss)
85 req.Header.Add("Accept", acceptHeader)
86
87 resp, err := t.tr.RoundTrip(req)
88 return resp, err
89 }
90
View as plain text