Zippytal-Node/config.go

181 lines
4.0 KiB
Go

package localserver
import (
"bytes"
"context"
"crypto/x509"
"encoding/json"
"encoding/pem"
"fmt"
"io"
"log"
"net/http"
"os"
"path/filepath"
"github.com/google/uuid"
)
var NodeToken string
var NodeID string
type LocalServerConfig struct {
configFilePath string
NodeId string `json:"nodeId"`
PrivateKeyPath string `json:"privateKeyPath"`
Token string `json:"token"`
}
func NewLocalServerConfig() (localServerConfig *LocalServerConfig, err error) {
logFile, err := os.OpenFile(filepath.Join("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)
localServerConfig = &LocalServerConfig{
configFilePath: filepath.Join("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("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 := http.Post("https://dev.zippytal.com/req", "application/json", bytes.NewBuffer(bss))
if postErr != nil {
logger.Println("e")
return postErr
}
logger.Println(res)
if err = file.Close(); err != nil {
return
}
} else if err != nil {
return
}
file, err := os.Open(l.configFilePath)
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)
if err != nil {
return
}
var buff []byte
buff, err = io.ReadAll(f)
if err != nil {
return
}
em := NewEncryptionManager()
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 := http.Post("https://app.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) {
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
}