WIP: Update to the go api.

This commit is contained in:
Jesse Malotaux 2025-03-24 20:22:31 +01:00
parent 03181cf6a4
commit 3b38372b4b
16 changed files with 317 additions and 30 deletions

View file

@ -67,6 +67,12 @@ func ApiPost(w http.ResponseWriter, r *http.Request) {
DeviceAccessCheck(w, r)
case "/device/access/request":
DeviceAccessRequest(w, r)
case "/device/link/ping":
PingLink(w, r)
case "/device/link/start":
StartLink(w, r)
case "/device/handshake":
Handshake(w, r)
case "/poll/remote":
PollRemote(w, r)

79
be/app/certify.go Normal file
View file

@ -0,0 +1,79 @@
package app
import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"math/big"
"os"
"time"
)
func generateCertificate() tls.Certificate {
fmt.Println("Generating certificate")
var certError = false
// Generate a private key
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
// fmt.Println(err)
certError = true
}
template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
Organization: []string{"Macrame-Server"},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(1, 0, 0),
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
}
certBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
if err != nil {
// fmt.Println(err)
certError = true
}
// Encode the certificate and private key to PEM
certPEM := pem.EncodeToMemory(
&pem.Block{Type: "CERTIFICATE", Bytes: certBytes},
)
keyPEM := pem.EncodeToMemory(
&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)},
)
// Save the certificate and private key to files
if err := os.WriteFile("server.crt", certPEM, 0644); err != nil {
// fmt.Println(err)
certError = true
}
if err := os.WriteFile("server.key", keyPEM, 0644); err != nil {
// fmt.Println(err)
certError = true
}
if !certError {
return Certify()
}
return tls.Certificate{}
}
func Certify() tls.Certificate {
fmt.Println("Loading certificate")
cert, err := tls.LoadX509KeyPair("server.crt", "server.key")
if err != nil {
return generateCertificate()
}
return cert
}

View file

@ -1,9 +1,12 @@
package app
import (
"be/app/helper"
"be/app/structs"
"encoding/json"
"fmt"
"log"
"math/rand"
"net/http"
"os"
"path/filepath"
@ -72,10 +75,7 @@ func PollRemote(w http.ResponseWriter, r *http.Request) {
func DeviceAccessCheck(w http.ResponseWriter, r *http.Request) {
log.Println("device access check")
}
func DeviceAccessRequest(w http.ResponseWriter, r *http.Request) {
var req structs.RemoteWebhook
var req structs.Check
err := json.NewDecoder(r.Body).Decode(&req)
@ -84,10 +84,103 @@ func DeviceAccessRequest(w http.ResponseWriter, r *http.Request) {
return
}
log.Println(req)
// mu.Lock()
// queue[req.Device] = append(queue[req.Device], req)
// mu.Unlock()
_, errSett := os.Stat("devices/" + req.Uuid + ".json")
_, errKey := os.Stat("devices/" + req.Uuid + ".pem")
log.Println(errSett, errKey)
if (errSett == nil) && (errKey == nil) {
log.Println("authorized")
json.NewEncoder(w).Encode("authorized")
} else if (errSett == nil) && (errKey != nil) {
log.Println("requested")
json.NewEncoder(w).Encode("requested")
} else {
log.Println("unauthorized")
json.NewEncoder(w).Encode("unauthorized")
}
return
}
func DeviceAccessRequest(w http.ResponseWriter, r *http.Request) {
var req structs.Request
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
deviceSettings := structs.Settings{Name: req.Name, Type: req.Type}
settingsJSON, err := json.Marshal(deviceSettings)
if err != nil {
log.Println(err)
return
}
err = os.WriteFile("devices/"+req.Uuid+".json", settingsJSON, 0644)
if err != nil {
log.Println(err)
return
}
json.NewEncoder(w).Encode(true)
}
func PingLink(w http.ResponseWriter, r *http.Request) {
log.Println("ping link")
var req structs.Check
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
json.NewEncoder(w).Encode(false)
return
}
var filename = "devices/" + req.Uuid + ".tmp"
_, err = os.ReadFile(filename)
if err == nil {
json.NewEncoder(w).Encode(true)
return
}
json.NewEncoder(w).Encode(false)
return
}
func StartLink(w http.ResponseWriter, r *http.Request) {
var req structs.Check
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
pin := fmt.Sprintf("%04d", rand.Intn(10000))
if helper.TempPinFile(req.Uuid, pin) {
json.NewEncoder(w).Encode(pin)
}
}
func Handshake(w http.ResponseWriter, r *http.Request) {
var req structs.Handshake
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
log.Println(req.Shake)
}

View file

@ -10,8 +10,6 @@ import (
)
func EndpointAccess(w http.ResponseWriter, r *http.Request) bool {
log.Println("endpoint access")
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
log.Fatal(err)
@ -19,13 +17,13 @@ func EndpointAccess(w http.ResponseWriter, r *http.Request) bool {
if (isLocal(ip) && isEndpointAllowed("Local", r.URL.Path)) ||
(isLanRemote(ip) && isEndpointAllowed("Remote", r.URL.Path)) {
log.Println("accessible")
log.Println(r.URL.Path, "endpoint access: accessible")
return true
} else if isLanRemote(ip) && isEndpointAllowed("auth", r.URL.Path) && isDeviceAuthorized() {
log.Println("authorized")
log.Println(r.URL.Path, "endpoint access: authorized")
}
log.Println(r.URL.Path, "not authorized or accessible")
log.Println(r.URL.Path, "endpoint access: not authorized or accessible")
return false
}

View file

@ -0,0 +1,27 @@
package helper
import (
"log"
"os"
"time"
)
func TempPinFile(Uuid string, pin string) bool {
log.Println("temp pin file", Uuid, pin)
err := os.WriteFile("devices/"+Uuid+".tmp", []byte(pin), 0644)
if err != nil {
log.Println(err)
return false
}
time.AfterFunc(1*time.Minute, func() {
log.Println("deleting", Uuid, pin)
os.Remove("devices/" + Uuid + ".tmp")
})
return true
}
func CheckPinFile(encryptedData []byte) bool {
return false
}

View file

@ -15,11 +15,17 @@ var Endpoints = Allowed{
"/device/list",
"/device/access/check",
"/device/access/request",
"/device/link/ping",
"/device/link/start",
"/device/handshake",
},
Remote: []string{
"/macro/list",
"/device/access/check",
"/device/access/request",
"/device/link/ping",
"/device/link/end",
"/device/handshake",
"/device/auth",
},
Auth: []string{

View file

@ -9,3 +9,17 @@ type RemoteWebhook struct {
Event string `json:"event"`
Data string `json:"data"`
}
type Check struct {
Uuid string `json:"uuid"`
}
type Request struct {
Uuid string `json:"uuid"`
Name string `json:"name"`
Type string `json:"type"`
}
type Handshake struct {
Shake string `json:"shake"`
}