-
Notifications
You must be signed in to change notification settings - Fork 6
/
authorization.go
135 lines (122 loc) · 3.94 KB
/
authorization.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package main
import (
"bytes"
"crypto/rsa"
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
"time"
jwt "github.com/dgrijalva/jwt-go"
)
var (
signKey *rsa.PrivateKey
)
var installationTokenResponse struct {
Token string `json:"token"`
}
var installationIDResponse struct {
ID int `json:"id"`
}
func getInstallationToken(env Environment) (string, error) {
request, err1 := getInstallationTokenRequest(env)
if err1 != nil {
return "", errors.New("failed to getInstallationTokenRequest")
}
body, _ := processRequest(request)
err3 := json.NewDecoder(bytes.NewReader(body)).Decode(&installationTokenResponse)
fatal(err3)
if err3 != nil {
return "", errors.New("failed to perform json.NewDecoder(bytes.NewReader(body)).Decode(&installationTokenResponse)")
}
log.Printf("Found installation token response %v", installationTokenResponse)
if &installationTokenResponse.Token == nil {
return "", errors.New("failed to get installation token response")
}
return installationTokenResponse.Token, nil
}
func getInstallationID(env Environment) (int, error) {
request, err := getInstallationIDRequest(GithubInstallationIDURI, env)
fatal(err)
if err != nil {
return 0, errors.New("Failed to perform getInstallationIDRequest")
}
body, _ := processRequest(request)
err2 := json.NewDecoder(bytes.NewReader(body)).Decode(&installationIDResponse)
fatal(err2)
if err2 != nil {
return 0, errors.New("Failed to perform json.NewDecoder(response.Body)")
}
log.Printf("Found installation id response %v from uri %v", installationIDResponse, GithubInstallationIDURI)
if &installationIDResponse.ID == nil {
return 0, errors.New("failed to get installation token response")
}
return installationIDResponse.ID, nil
}
func getInstallationIDRequest(uri string, env Environment) (*http.Request, error) {
jwt, err1 := getJwt(env.githubAppPrivateKey, env.githubAppIdentifier)
if err1 != nil {
return nil, errors.New("Failed to perform getJwt")
}
req, err := http.NewRequest("GET", uri, nil)
fatal(err)
if err != nil {
return nil, errors.New("Failed to perform getInstallationIDRequest")
}
getJwtHeaders(req, jwt)
return req, nil
}
func getInstallationTokenRequest(env Environment) (*http.Request, error) {
installaionID, err1 := getInstallationID(env)
if err1 != nil {
return nil, errors.New("Failed to perform getInstallationTokenRequest")
}
githubInstallationTokenURI := fmt.Sprintf(GithubAPIBase+"/app/installations/%v/access_tokens", installaionID)
log.Printf("Create request for getInstallationTokenRequest %v", githubInstallationTokenURI)
postBody, err2 := json.Marshal(map[string][]string{
"repositories": []string{env.repoName},
})
fatal(err2)
if err2 != nil {
return nil, errors.New("Failed to perform json.Marshal")
}
requestBody := bytes.NewBuffer(postBody)
jwt, err := getJwt(env.githubAppPrivateKey, env.githubAppIdentifier)
if err != nil {
return nil, errors.New("Failed to perform getJwt")
}
req, err3 := http.NewRequest("POST", githubInstallationTokenURI, requestBody)
fatal(err3)
if err3 != nil {
return nil, errors.New("Failed to perform http.NewRequest")
}
getJwtHeaders(req, jwt)
return req, nil
}
func getGithubBaseHeaders(req *http.Request) {
req.Header.Add("Accept", "application/vnd.github.v3+json")
}
func getJwtHeaders(req *http.Request, jwt string) {
getGithubBaseHeaders(req)
req.Header.Add("Authorization", fmt.Sprintf("Bearer %v", jwt))
}
func initSignKey(privateKey []byte) {
var err error
signKey, err = jwt.ParseRSAPrivateKeyFromPEM(privateKey)
fatal(err)
}
func getJwt(privateKey []byte, appIdentifier string) (string, error) {
initSignKey(privateKey)
t := jwt.New(jwt.GetSigningMethod("RS256"))
claims := t.Claims.(jwt.MapClaims)
claims["exp"] = time.Now().Add(time.Minute * 1).Unix()
claims["iat"] = time.Now().Unix()
claims["iss"] = appIdentifier
tokenString, err := t.SignedString(signKey)
fatal(err)
if err != nil {
return "", errors.New("Failed to perform t.SignedString(signKey)")
}
return tokenString, nil
}