210 lines
4.7 KiB
Go
210 lines
4.7 KiB
Go
package localserver
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"crypto/x509"
|
|
"encoding/json"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
var NodeToken string
|
|
var NodeID string
|
|
var HTTPClient *http.Client
|
|
|
|
type LocalServerConfig struct {
|
|
configFilePath string
|
|
NodeId string `json:"nodeId"`
|
|
PrivateKeyPath string `json:"privateKeyPath"`
|
|
Token string `json:"token"`
|
|
}
|
|
|
|
var configPath = ""
|
|
|
|
func NewLocalServerConfig(appConfigPath string) (localServerConfig *LocalServerConfig, err error) {
|
|
HTTPClient = &http.Client{
|
|
Transport: &http.Transport{
|
|
DisableKeepAlives: true,
|
|
MaxIdleConns: 1,
|
|
MaxIdleConnsPerHost: 1,
|
|
MaxConnsPerHost: 1,
|
|
},
|
|
Timeout: 10 * time.Second,
|
|
}
|
|
configPath = appConfigPath
|
|
logFile, err := os.OpenFile(filepath.Join(configPath, "local_server.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755)
|
|
if err != nil {
|
|
return
|
|
}
|
|
logger.SetOutput(logFile)
|
|
logger.SetFlags(log.Ldate | log.LUTC | log.Lshortfile | log.Ltime | log.LstdFlags | log.Lmsgprefix)
|
|
if _, err = os.Stat(filepath.Join(configPath, "config")); err != nil {
|
|
if os.IsNotExist(err) {
|
|
if err = os.MkdirAll(filepath.Join(configPath, "config"), 0770); err != nil {
|
|
return
|
|
}
|
|
} else {
|
|
return
|
|
}
|
|
}
|
|
localServerConfig = &LocalServerConfig{
|
|
configFilePath: filepath.Join(configPath, "config", "node_config.json"),
|
|
}
|
|
err = localServerConfig.startup()
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = localServerConfig.authenticate()
|
|
return
|
|
}
|
|
|
|
func (l *LocalServerConfig) startup() (err error) {
|
|
if _, err = os.Stat(l.configFilePath); os.IsNotExist(err) {
|
|
file, fileErr := os.Create(l.configFilePath)
|
|
if fileErr != nil {
|
|
return fileErr
|
|
}
|
|
id := uuid.NewString()
|
|
e := NewEncryptionManager()
|
|
keypair, keyErr := e.GenerateKeyPair(context.Background(), id, "")
|
|
if keyErr != nil {
|
|
return keyErr
|
|
}
|
|
baseConfig := map[string]interface{}{
|
|
"nodeId": id,
|
|
"privKeyPath": filepath.Join(configPath, "config", id),
|
|
"token": "",
|
|
}
|
|
bs, marshallErr := json.Marshal(&baseConfig)
|
|
if marshallErr != nil {
|
|
return marshallErr
|
|
}
|
|
_, writeErr := file.Write(bs)
|
|
if writeErr != nil {
|
|
return writeErr
|
|
}
|
|
key_bytes := x509.MarshalPKCS1PublicKey(&keypair.PublicKey)
|
|
key := pem.EncodeToMemory(&pem.Block{
|
|
Type: "RSA PUBLIC KEY",
|
|
Bytes: key_bytes,
|
|
})
|
|
// logger.Println(string(key))
|
|
l.NodeId = id
|
|
l.PrivateKeyPath = ""
|
|
l.Token = ""
|
|
bss, marshallErr := json.Marshal(map[string]interface{}{
|
|
"type": "create_node",
|
|
"from": id,
|
|
"to": "serv",
|
|
"token": "",
|
|
"peerType": "node",
|
|
"payload": map[string]string{
|
|
"nodeId": id,
|
|
"nodeKey": string(key),
|
|
"nodeUsername": "anonymous",
|
|
},
|
|
})
|
|
if marshallErr != nil {
|
|
return marshallErr
|
|
}
|
|
res, postErr := HTTPClient.Post("https://dev.zippytal.com/req", "application/json", bytes.NewBuffer(bss))
|
|
if postErr != nil {
|
|
// logger.Println("e")
|
|
fmt.Println("error is from there")
|
|
return postErr
|
|
}
|
|
// logger.Println(res)
|
|
fmt.Println(res)
|
|
if err = file.Close(); err != nil {
|
|
return
|
|
}
|
|
} else if err != nil {
|
|
return
|
|
}
|
|
file, err := os.Open(l.configFilePath)
|
|
defer file.Close()
|
|
if err != nil {
|
|
return
|
|
}
|
|
var config map[string]string
|
|
err = json.NewDecoder(file).Decode(&config)
|
|
if err != nil {
|
|
return
|
|
}
|
|
// logger.Println(config)
|
|
NodeID = l.NodeId
|
|
l.NodeId = config["nodeId"]
|
|
l.PrivateKeyPath = config["privKeyPath"]
|
|
l.Token = config["token"]
|
|
return
|
|
}
|
|
|
|
func (l *LocalServerConfig) authenticate() (err error) {
|
|
f, err := os.Open(l.PrivateKeyPath)
|
|
defer f.Close()
|
|
if err != nil {
|
|
return
|
|
}
|
|
var buff []byte
|
|
buff, err = io.ReadAll(f)
|
|
if err != nil {
|
|
return
|
|
}
|
|
em := NewEncryptionManager()
|
|
fmt.Println("-----------", l.NodeId)
|
|
sig, err := em.SignRequest(string(buff), l.NodeId)
|
|
if err != nil {
|
|
return
|
|
}
|
|
body, err := json.Marshal(map[string]interface{}{
|
|
"type": "login_key_node",
|
|
"from": l.NodeId,
|
|
"peerType": "node",
|
|
"payload": map[string]string{
|
|
"id": l.NodeId,
|
|
"signature": sig,
|
|
},
|
|
})
|
|
if err != nil {
|
|
return
|
|
}
|
|
res, err := HTTPClient.Post("https://dev.zippytal.com/req", "application/json", bytes.NewBuffer(body))
|
|
if err != nil {
|
|
return
|
|
}
|
|
bs, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
return
|
|
}
|
|
var payload map[string]any
|
|
if err = json.Unmarshal(bs, &payload); err != nil {
|
|
return
|
|
}
|
|
err = l.handleLoginResponse(payload)
|
|
NodeID = l.NodeId
|
|
return
|
|
}
|
|
|
|
func (l *LocalServerConfig) handleLoginResponse(res map[string]any) (err error) {
|
|
fmt.Println("----------", res)
|
|
if _, ok := res["token"]; !ok {
|
|
err = fmt.Errorf("no field token in res")
|
|
return
|
|
}
|
|
if _, ok := res["token"].(string); !ok {
|
|
err = fmt.Errorf("field token not string in res")
|
|
return
|
|
}
|
|
NodeToken = res["token"].(string)
|
|
return
|
|
}
|