-
Notifications
You must be signed in to change notification settings - Fork 0
/
initBot.go
186 lines (145 loc) · 4.79 KB
/
initBot.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package main
import (
"bytes"
"crypto/x509"
"encoding/json"
"encoding/pem"
"io/ioutil"
"net/http"
"os"
"strconv"
"time"
"github.com/dgrijalva/jwt-go"
log "github.com/sirupsen/logrus"
)
type config struct {
SessionAuthHost string `json:"sessionAuthHost"`
SessionAuthPort int `json:"sessionAuthPort"`
KeyAuthHost string `json:"keyAuthHost"`
KeyAuthPort int `json:"keyAuthPort"`
PodHost string `json:"podHost"`
PodPort int `json:"podPort"`
AgentHost string `json:"agentHost"`
AgentPort int `json:"agentPort"`
AuthType string `json:"authType"`
BotCertPath string `json:"botCertPath"`
BotCertName string `json:"botCertName"`
BotCertPassword string `json:"botCertPassword"`
BotPrivateKeyPath string `json:"botPrivateKeyPath"`
BotPrivateKeyName string `json:"botPrivateKeyName"`
BotUsername string `json:"botUsername"`
BotEmailAddress string `json:"botEmailAddress"`
AppCertPath string `json:"appCertPath"`
AppCertName string `json:"appCertName"`
AppCertPassword string `json:"appCertPassword"`
ProxyURL string `json:"proxyURL"`
ProxyUsername string `json:"proxyUsername"`
ProxyPassword string `json:"proxyPassword"`
AuthTokenRefreshPeriod string `json:"authTokenRefreshPeriod"`
}
type authenticateResp struct {
Token string `json:"token"`
Name string `json:"name"`
}
func init() {
log.SetFormatter(&log.JSONFormatter{})
log.SetOutput(os.Stdout)
}
func initBot(configPath string) (botClientInit *botClient) {
botClientInit = new(botClient)
content, err := ioutil.ReadFile(configPath)
if err != nil {
log.Fatal(err.Error())
}
if err := json.Unmarshal(content, &botClientInit.config); err != nil {
log.Fatal(err.Error())
}
authenticate(botClientInit)
return botClientInit
}
func authenticate(botClient *botClient) {
keyData, err := ioutil.ReadFile(botClient.config.BotPrivateKeyPath + botClient.config.BotPrivateKeyName)
if err != nil {
log.Fatal(err.Error())
}
privateKeyBlock, _ := pem.Decode(keyData)
// parsing the privateKey from decoded keyData
secretKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
if err != nil {
log.Fatal(err.Error())
}
// jwt payload info
claims := jwt.StandardClaims{
Subject: botClient.config.BotUsername,
IssuedAt: time.Now().Unix(),
ExpiresAt: time.Unix(time.Now().Unix(), 0).Add(5 * time.Minute).Unix(),
}
unSignedToken := jwt.NewWithClaims(jwt.SigningMethodRS512, claims)
token, err := unSignedToken.SignedString(secretKey)
if err != nil {
log.Fatal(err.Error())
}
tokenJSON := `{"token":"` + token + `"}`
sessionAuthenticate(botClient, tokenJSON)
kmAuthenticate(botClient, tokenJSON)
log.Info("the bot is authenticated successfully!")
}
func sessionAuthenticate(botClient *botClient, tokenJSON string) {
req, _ := http.NewRequest(
"POST",
"https://"+botClient.config.SessionAuthHost+":"+strconv.Itoa(botClient.config.SessionAuthPort)+"/login/pubkey/authenticate",
bytes.NewBuffer([]byte(tokenJSON)),
)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.WithFields(log.Fields{
"result": "cannot connect to sessionAuth API. \ncheck if sessionAuthHost or sessionAuthPort in config.json is correct.",
}).Fatal(err.Error())
}
switch resp.StatusCode {
case 401:
log.Fatal("Cannot authenticate user, please check if your RSA key pair is correct.")
case 200:
log.Info("received session token successfully.")
default:
log.Error(resp)
}
defer resp.Body.Close()
data := new(authenticateResp)
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
log.Fatal(err.Error())
}
resp.Body.Close()
botClient.sessionToken = data.Token
}
func kmAuthenticate(botClient *botClient, tokenJSON string) {
req, _ := http.NewRequest(
"POST",
"https://"+botClient.config.KeyAuthHost+":"+strconv.Itoa(botClient.config.KeyAuthPort)+"/relay/pubkey/authenticate",
bytes.NewBuffer([]byte(tokenJSON)),
)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.WithFields(log.Fields{
"result": "cannot connect to keyManagerAuth API. \ncheck if keyAuthHost or keyAuthPort in config.json is correct.",
}).Fatal(err.Error())
}
switch resp.StatusCode {
case 401:
log.Fatal("Cannot authenticate user, please check if your RSA key pair is correct.")
case 200:
log.Info("received keymanager token successfully.")
default:
log.Error(resp)
}
defer resp.Body.Close()
data := new(authenticateResp)
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
log.Fatal(err.Error())
}
botClient.kmToken = data.Token
}