refactorment and addition of code.

This commit is contained in:
Daan Selen
2025-05-15 10:28:05 +02:00
parent a2ba67eb26
commit c8d869508e
15 changed files with 250 additions and 37 deletions

7
server/build.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
echo "Building..."
cd src/ || exit 1
go build -o ../
cd ..
echo "Done."

29
server/cert/cert.pem Normal file
View File

@@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFCTCCAvGgAwIBAgIUfKEEZwKU9u9YgeHe6hkJTis6UQwwDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI1MDUxNTA2NDg0OFoXDTI2MDUx
NTA2NDg0OFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEAxWiPe1gQn8ac1DZR/jvzFxMcCq4Wyh0mNWaI0Yi57tiE
4ZpaTVhUGYmcN7woDjIJH/db1MeeCtWPZQswVfH3XK2p3UAU+eVie4C/ydAktG4R
EhfDjixVDhcGfQ0aAMPod4/Qeelk0ffAW2oUCltGKfm+pHR3fbFbtPTtI1r1bA9n
GDIMMIAwzEklkw96VZiZzJGWTV3KTyDZ0an6fWftFixiy99oqyrD60YP7uuVpbnu
A1sUzOiPL3ZiMd9KXZ3I6wMnI9EUc4Z4Rm4sd3KdEWcCalZsd8JJOM4r8mnSImJe
7VWLFlJz/dmbY0AYqkhF/e/NlHQx9SoardLLeykuOvs2M5V/uwOlQpanv4A8HzPK
cGysNvz5C7L1hkwyGdYQ83IJK2PvV4kR28+e0Z7tqdnR19tuKd47FLbKq3DB1vni
zPzBeJteyC4Z/l3su8x1NJL9vNe4xVycywk2dq7oZKxse4jP9N0VBKoSUGn+1vVn
L6UvYlnZJpDvZ2TXSpCQd8Ru9nbQu3k5kG8fCfwK5EAWQ/k6hRJKoDBpEaYe5ENa
qYF02s04zGRNAPvDlljbninJn9we0f9gTHbo3u5RELqI9M7FKEO78Wl3qnst4YKa
icmp4U9f3JrhR4NM5HGSQ65phwGK1kC7VNUxItV2vV0YFWLnIqnwX09esKJJXAEC
AwEAAaNTMFEwHQYDVR0OBBYEFDYoFgMXo/MEmTf/QK8FBEoYsafzMB8GA1UdIwQY
MBaAFDYoFgMXo/MEmTf/QK8FBEoYsafzMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
hvcNAQELBQADggIBACnhI7xTPTGoL0adHQtdicYO7UdgMBcpVPTdoFigFwhq+cxz
2Jk/8fJbD6srBW9iiNFET4vOYtjCxOpAuMJkEBl+dWIBZOa2QaRjgiguXNZe4yu1
egTbUTr8qgB5oU+kMXYLuHIe+QAJ8Yz4XdGa0kYm/K8YSF6C9n7z8dk9I0In789z
VFUP6HTuYS6q0LmstJ/op4J549FZm3IF5bwZTnYTAcWKyk6Gx9nofWtYhfOGnB7E
m7K3qDUcPRdU8hmTDLdPCh07BTVpPbLyzgCslahQiMQuFVOBNh0xtgwjYt60wo6n
lvgi5MOQty+unLX28Hn7NnMawEkAhoQMLGjidTNsHGvtxRLTVwXjWJH2cQ5L/Vch
apu72JJjkFofsDV+lE9U93YWwULzodVW7hAlx0gfop834PJmmX/IwCNvrF69+qMh
EsU/dHgyI6Rt3Xa8SYu/yoEsNMIX1EAFFrh9W3BUr12GSIyYoJdamIWUshDiGz4J
JTYHNNfswEa4QwcXMAS+ZHAXQxZxz995IOYZlAdpSJlCVz5vXvgaykEDo7g3KuDO
E3RazsW9iPhlUskgnmFFxVQW4AxGTplFzMcNQoMXhs/LjnLb2zkeDyW2o9H9I8Ow
GNUA5CXEGfrTcpt5ujRvH/x34GEN2NfPLPweDTVrgJLA2xuXMfWYauKg2vhV
-----END CERTIFICATE-----

52
server/cert/key.pem Normal file
View File

@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
bqf33hxozZ2xpA+19JwXMvyAiEtbiDM=
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,8 @@
[ghostserver]
address = 0.0.0.0:19070
secure = true
certfile = ./cert/cert.pem
keyfile = ./cert/key.pem
interval = 600

BIN
server/ghostrunner-server Executable file

Binary file not shown.

View File

@@ -2,4 +2,9 @@ module ghostrunner-server
go 1.24.3 go 1.24.3
require github.com/gorilla/mux v1.8.1 require (
github.com/gorilla/mux v1.8.1
gopkg.in/ini.v1 v1.67.0
)
require github.com/stretchr/testify v1.10.0 // indirect

View File

@@ -1,2 +1,12 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -1,5 +1,20 @@
package main package main
func main() { import (
"flag"
"fmt"
"ghostrunner-server/modules/confread"
"ghostrunner-server/modules/restapi"
"log"
)
func main() {
// Begin by trying to find the configuration file.
confPtr := flag.String("conf", "./conf/ghostserver.conf", "Specify a config file location yourself. Relative to the program.")
config := confread.ReadConf(*confPtr)
log.Println("Starting the API-Server backend.")
restapi.InitApiServer(config)
fmt.Scanln()
} }

View File

@@ -0,0 +1,34 @@
package confread
import (
"ghostrunner-server/modules/utilities"
"gopkg.in/ini.v1"
)
const (
configSection = "ghostserver"
)
func ReadConf(configPath string) ConfigStruct {
inidata, err := ini.Load(configPath)
utilities.HandleError(err, "Trying to load the ini config file!")
section := inidata.Section(configSection)
var config ConfigStruct
config.Address = section.Key("address").String()
utilities.HandleError(err, "Trying to parse apiport field into the struct!")
config.Secure, err = section.Key("secure").Bool()
utilities.HandleError(err, "Trying to parse https field into the struct!")
config.CertFile = section.Key("certfile").String()
config.KeyFile = section.Key("keyfile").String()
config.Interval, err = section.Key("interval").Int()
utilities.HandleError(err, "Trying to parse interval field into the struct!")
return config
}

View File

@@ -0,0 +1,9 @@
package confread
type ConfigStruct struct {
Address string
Secure bool
CertFile string
KeyFile string
Interval int
}

View File

@@ -0,0 +1,5 @@
package database
func InitSqlite() {
}

View File

@@ -0,0 +1,14 @@
package restapi
import (
"ghostrunner-server/modules/utilities"
"net/http"
"github.com/gorilla/mux"
)
func handleSchedule(w http.ResponseWriter, r *http.Request) {
action := mux.Vars(r)["action"]
utilities.ConsoleLog("Funky Funky " + action)
}

View File

@@ -1,46 +1,61 @@
package restapi package restapi
import ( import (
"crypto/tls"
"encoding/json" "encoding/json"
"log" "ghostrunner-server/modules/confread"
"ghostrunner-server/modules/utilities"
"net/http" "net/http"
"time"
"github.com/gorilla/mux" "github.com/gorilla/mux"
) )
const ( const (
defaultMessage = "GhostRunner Server, HTTP REST API. Version: 0.0.1." defaultMessage = "GhostRunner Server, HTTP REST API. Version: 0.0.1."
readWriteTimeout = 30 * time.Second //Seconds
) )
func rootEndpointHandler(w http.ResponseWriter, r *http.Request) { func rootEndpointHandler(w http.ResponseWriter, r *http.Request) { // This endpoint handles has been placed in the init section because its basic.
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
log.Println("ROOT HIT") //Comment out later, for debugging purposes utilities.ConsoleLog("ROOT HIT") //Comment out later, for debugging purposes
json.NewEncoder(w).Encode(infoResponse{ json.NewEncoder(w).Encode(infoResponse{
Status: http.StatusOK, Status: http.StatusOK,
Message: defaultMessage, Message: defaultMessage,
}) })
} }
func _initApiServer(secureServer bool, apiKey, apiCert, apiPort string) { func InitApiServer(cfg confread.ConfigStruct) {
apiRouter := mux.NewRouter().StrictSlash(true) // Initialize the HTTP REST API Router. rtr := createRouter()
srv := createServer(cfg, rtr)
apiRouter.HandleFunc("/", rootEndpointHandler).Methods("GET") go func() {
var err error
if secureServer { // If a secured server is wanted. Use the specified certificate files. if cfg.Secure {
httpServer := &http.Server{ err = srv.ListenAndServeTLS(cfg.CertFile, cfg.KeyFile)
Addr: apiPort, // Specify the desired HTTPS port. } else {
Handler: apiRouter, // Specify the above created handler. err = srv.ListenAndServe()
TLSConfig: &tls.Config{
Certificates: []tls.Certificate{ // Load the certificate and private key.
loadTLSCertificate(apiCert, apiKey),
},
},
} }
go httpServer.ListenAndServeTLS("", "") utilities.HandleError(err, "Initializing the HTTP REST API!")
} else { }()
go http.ListenAndServe(":"+apiPort, apiRouter) // Transform string slightly to make the expected format. utilities.ConsoleLog("Successfully started the GhostServer goroutine.")
}
func createRouter() *mux.Router {
r := mux.NewRouter().StrictSlash(true)
r.HandleFunc("/", rootEndpointHandler).Methods("GET")
r.HandleFunc("/schedule/{action:register|deregister}", handleSchedule).Methods("POST")
return r
}
func createServer(cfg confread.ConfigStruct, ghostHandler http.Handler) *http.Server {
return &http.Server{
Addr: cfg.Address, // Specify the desired HTTPS port.
Handler: ghostHandler, // Specify the above created handler.
ReadTimeout: readWriteTimeout,
WriteTimeout: readWriteTimeout,
} }
} }

View File

@@ -1,14 +0,0 @@
package restapi
import (
"crypto/tls"
"log"
)
func loadTLSCertificate(certFile, keyFile string) tls.Certificate {
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
log.Fatal(err)
}
return cert
}

View File

@@ -0,0 +1,24 @@
package utilities
import (
"crypto/tls"
"log"
)
func HandleError(err error, task string) {
if err != nil {
log.Fatal("The program crashed unexpectedly while doing: "+task+"\nThe following exception occured:", err)
}
}
func ConsoleLog(message string) {
log.Println(message)
}
func LoadCertificate(certFile, keyFile string) tls.Certificate {
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
log.Fatal(err)
}
return cert
}